//#include "StdAfx.h"
#include "EventSocket.h"

CEventSocket::CEventSocket(void)
{
	m_pfCallback = NULL;
}

CEventSocket::~CEventSocket(void)
{
}
void CEventSocket::SetCallback( PFN_SOCK_ON_EVENT pFN )
{
	m_pfCallback = pFN;
}

bool CEventSocket::Create( int nProtocol /*= IPPROTO_TCP*/, unsigned short uPort/* = 0*/ )
{
	m_uState = SOCK_STATE_NOTSOCK;
	CEventSocket::Close();

	if( base_sock::Create( (IPPROTO_TCP == nProtocol ? SOCK_STREAM : SOCK_DGRAM), nProtocol ) )
	{
		m_uState = SOCK_STATE_CREATED;
		return true;
	}
	return false;
}
bool CEventSocket::Listen( int nBlock /*= 5*/ )
{
	if( m_uState != SOCK_STATE_BINDED )
	{
		return false;
	}
	if( !base_sock::Listen( nBlock ) )
	{
		return false;
	}
	m_uState = SOCK_STATE_LISTENING;
	return true;
}
bool CEventSocket::Connect( SOCKADDR_IN * pAddr )
{
	if( m_uState == SOCK_STATE_NOTSOCK || m_uState == SOCK_STATE_CLOSED )
	{
		return false;
	}
	m_uState = SOCK_STATE_CONNECTING;

	if( !base_sock::Connect( pAddr ) )
	{
		m_uState = SOCK_STATE_CONNECT_FAILED;
		return false;
	}
	m_uState = SOCK_STATE_CONNECTED;

	return true;
}
bool CEventSocket::Bind( SOCKADDR_IN * pAddr )
{
	if( m_uState != SOCK_STATE_CREATED )
	{
		return false;
	}

	if( !base_sock::Bind( pAddr ) )
	{
		return false;
	}
	m_uState = SOCK_STATE_BINDED;
	return true;
}
void CEventSocket::ShutDown( int nArg )
{

}
void CEventSocket::Close()
{
	base_sock::Close( true );
	m_uState = SOCK_STATE_CLOSED;
	m_bCanRecv = false;
}

void CEventSocket::SetParam( void * arg )
{
	m_pParam = arg;
}
unsigned char CEventSocket::GetState()
{
	return m_uState;
}
bool CEventSocket::CanRecv()
{
	return m_bCanRecv;
}
void CEventSocket::OnReceive( int nErrorCode )
{
	if( !nErrorCode )
	{
		m_bCanRecv= true;
		if( m_pfCallback != NULL )
		{
			m_pfCallback( this, SOCK_EVENT_CAN_READ, m_pParam );
		}
	} 
	else
	{
		CEventSocket::Close();
		if( m_pfCallback ) 
		{
			m_pfCallback( this, SOCK_EVENT_CLOSED, m_pParam );
		}
	}
}
void CEventSocket::OnSend( int nErrorCode )
{
	if( !nErrorCode )
	{
		if( m_pfCallback ) 
		{
			m_pfCallback( this, SOCK_EVENT_CAN_WRITE, m_pParam );
		}
	} 
	else 
	{
		CEventSocket::Close();
		if( m_pfCallback )
		{
			m_pfCallback( this, SOCK_EVENT_CLOSED, m_pParam );
		}
	}
}
void CEventSocket::OnOutOfBandData( int nErrorCode )
{
	if( !nErrorCode )
	{
		if( m_pfCallback ) 
		{
			m_pfCallback( this, SOCK_EVENT_CAN_READ_OOB, m_pParam );
		}
	} 
	else
	{
		CEventSocket::Close();
		if( m_pfCallback )
		{
			m_pfCallback( this, SOCK_EVENT_CLOSED, m_pParam );
		}
	}
}
void CEventSocket::OnAccept( int nErrorCode )
{
	if( !nErrorCode ) 
	{
		if( m_pfCallback )
		{
			m_pfCallback( this, SOCK_EVENT_CAN_ACCEPT, m_pParam );
		}
	}
}
void CEventSocket::OnClose( int nErrorCode )
{
	CEventSocket::Close();
	if( m_pfCallback ) 
	{
		m_pfCallback( this, SOCK_EVENT_CLOSED, m_pParam );
	}
}
void CEventSocket::OnConnect( int nErrorCode )
{
	m_uState = nErrorCode ? SOCK_STATE_CONNECT_FAILED : SOCK_STATE_CONNECTED; 
	if( m_pfCallback )
	{
		m_pfCallback( this, nErrorCode ? SOCK_EVENT_CONNECT_FAILED : SOCK_EVENT_CONNECT_OK, m_pParam );
	}
}